// Copyright DustedPixels.com 2008. All rights reserved.

package com.dustedpixels.jasmin.cpu;

import java.util.LinkedList;
import java.util.Queue;

import com.dustedpixels.common.Threads;
import com.dustedpixels.jasmin.common.Synchronizer;

/**
 * @author micapolos@gmail.com (Michal Pociecha-Los)
 */
public final class SynchronizerImpl implements Synchronizer {
  private final Callback[] callbacks;
  private Controller[] controllers;

  public SynchronizerImpl(Callback[] callbacks) {
    this.callbacks = callbacks;
    
    this.controllers = new Controller[callbacks.length];
    for (int i = 0; i < controllers.length; i++) {
      this.controllers[i] = new ControllerImpl(callbacks[i]);
    }
  }
  
  public Controller[] getControllers() {
    return null;
  }
  
  private final class ControllerImpl implements Controller {
    private final Syncer syncer;
    private final Callback callback;
    private long cycles = 0;
    private long noWriteUntil = 0;
    private boolean flush = false;
    private final Queue<Long> writeCyclesQueue;

    public ControllerImpl(Syncer syncer, Callback callback) {
      this.syncer = syncer;
      this.callback = callback;
      this.writeCyclesQueue = new LinkedList<Long>();
    }
    
    public void flush() {
      if (context.othersMinCycles() < cycles) {
        
        synchronized (context.mutex()) {
          Threads.waitOn(context.mutex());
        }
      }
    }

    public void noWriteUntil(long cycles) {
      noWriteUntil = cycles;
    }

    public void read() {
      // TODO Auto-generated method stub
      
    }

    public void waitUntil(long cycles) {
      this.cycles = cycles;
      
    }

    public void write() {
      writeCyclesQueue.offer(cycles);
    }
  }
  
  private interface Syncer {
    Context sync();
  }
  
  private interface Context {
    long othersNoWriteUntil();
    long othersMinCycles();
  }
  
  private interface Buffer {
    void enqueue();
  }
}
